package com.xiangxiao.rpan.authority.utils;

import com.xiangxiao.rpan.authority.tree.Tree;
import com.xiangxiao.rpan.authority.tree.TreeNode;
import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @Projectname:
 * @Author: xiangxiao
 * @Email: 573768011@qq.com
 * @Data:2023/3/29 0:55
 */
public class TreeUtil {

  /**TreeUtil
   * 模块递归父节点
   *
   * @param ids      结果，获取所有父节点id
   * @param nodeId   从哪个nodeId节点开始向上递归
   * @param allTree  数据源，递归过程中不变
   * @param downTree 树数据源，递归过程中逐渐变小
   * @param treeStr  用哪个tree "allTree"或者"downTree"
   * @param clss     buildTree时，传入的节点类型
   * @return
   */
  public static List<Long> getTreeParentIdList(List<Long> ids, Long nodeId, Tree allTree, Tree downTree, String treeStr, Class<? extends TreeNode> clss) {
    if (allTree == null || downTree == null) {
      return new ArrayList<>();
    } else {
      Tree tree = null;
      if ("allTree".equals(treeStr)) {
        tree = allTree;
      } else {
        tree = downTree;
      }
      TreeNode area = tree.treeNode(clss, nodeId);
      if (area != null) {
        ids.add(nodeId);
        Long parentId = area.getParentId();
        //0代表顶级节点
        Long rootNode = 0L;
        if (rootNode.equals(parentId)) {
          return ids;
        } else {
          getTreeParentIdList(ids, parentId, allTree, downTree, "allTree", clss);
        }
      } else {
        Tree tree1 = null;
        for (int i = 0, ii = tree.getRootList().size(); i < ii; i++) {
          List<TreeNode> allArea = tree.child((Class<TreeNode>) clss, tree.getRootList().get(i).getId());
          Tree.TreeBuilder builder = Tree.TreeBuilder.newInstance();
          if (CollectionUtils.isNotEmpty(allArea)) {
            builder.add(clss, allArea);
            tree1 = builder.build();
          }
          if (tree1 != null) {
            getTreeParentIdList(ids, nodeId, allTree, tree1, "downTree", clss);
          }
        }
      }
    }
    return ids;
  }


  /**
   * 向下递归，获取treeId节点及以下的树
   *
   * @param treeNodeList 结果
   * @param treeId       需要找到treeId节点及以下的一棵树
   * @param tree         数据源
   * @param clss         buildTree时，传入的节点类型
   * @return
   */
  public static List<TreeNode> filterAreaTreeNodes(List<TreeNode> treeNodeList, Long treeId, Tree tree, Class<? extends TreeNode> clss) {
    if (null != tree) {
      if (0 == treeId) {
        treeNodeList.addAll(tree.getRootList());
      } else {
        TreeNode area = tree.treeNode(clss, treeId);
        if (null != area) {
          treeNodeList.add(area);
        } else {
          Tree tree1 = null;
          for (int i = 0, ii = tree.getRootList().size(); i < ii; i++) {
            List<TreeNode> allArea = tree.child((Class<TreeNode>) clss, tree.getRootList().get(i).getId());
            Tree.TreeBuilder builder = Tree.TreeBuilder.newInstance();
            if (CollectionUtils.isNotEmpty(allArea)) {
              builder.add(clss, allArea);
              tree1 = builder.build();
            }
            if (tree1 != null) {
              filterAreaTreeNodes(treeNodeList, treeId, tree1, clss);
            }
          }

        }
      }
    }
    return treeNodeList;
  }

  /**
   * 找出这棵树所有的节点id
   *
   * @param treeNodes 树
   * @param longs     返回结果
   * @return
   */
  public static List<Long> recursionByTreeNodes(List<TreeNode> treeNodes, List<Long> longs) {

    if (CollectionUtils.isEmpty(treeNodes)) {
      return longs;
    } else {
      for (int i = 0, ii = treeNodes.size(); i < ii; i++) {
        longs.add(treeNodes.get(i).getId());
        List<TreeNode> treeNodes1 = treeNodes.get(i).getChildList();
        if (CollectionUtils.isNotEmpty(treeNodes1)) {
          recursionByTreeNodes(treeNodes1, longs);
        }
      }
    }
    return longs;
  }

  /**
   * 查出tree里面某个节点id下面所有的子节点id
   *
   * @param tree     数据源
   * @param parentId 父id
   * @param clss     buildTree时，传入的节点类型
   * @return
   */
  public static List<Long> findIdByParentId(Tree tree, Long parentId, Class<? extends TreeNode> clss) {
    //构造成一个树
    List<TreeNode> treeNodes = new ArrayList<>();
    TreeUtil.filterAreaTreeNodes(treeNodes, parentId, tree, clss);
    //从树中取出所有的orgid
    List<Long> subOrgIdList = new ArrayList<>();
    TreeUtil.recursionByTreeNodes(treeNodes, subOrgIdList);
    return subOrgIdList;
  }

  /**
   * 根据数据和节点类型构造成一棵树
   *
   * @param data
   * @param clss
   * @return
   */
  public static Tree buildTree(List<? extends TreeNode> data, Class<? extends TreeNode> clss) {
    Tree.TreeBuilder builder = Tree.TreeBuilder.newInstance();
    if (!CollectionUtils.isEmpty(data)) {
      builder.add(clss, data);
    }
    return builder.build();
  }
}
